﻿using DryIoc;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Threading.Tasks;
using System.Windows.Input;

namespace L3_Command.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        #region Test1_基本使用
        private string _test1_Time;
        public string Test1_CurrentTime
        {
            get { return _test1_Time; }
            set { SetProperty(ref _test1_Time, value); }
        }

        public DelegateCommand Test1_UpdateTime { get; set; }

        void Test1_UpdateTimeText()
        {
            Test1_CurrentTime = DateTime.Now.ToString();
        }
        #endregion

        #region Test2_带参数的命令
        private string _test2_CurrentTime;
        public string Test2_CurrentTime
        {
            get { return _test2_CurrentTime; }
            set { SetProperty(ref _test2_CurrentTime, value); }
        }

        public DelegateCommand<string> Test2_UpdateTime { get; set; }
        void Test2_UpdateTimeText(string parameter)
        {
            Test2_CurrentTime = DateTime.Now.ToString(parameter);
        }
        #endregion

        #region Test3_带CanExcute和CanExcuteChanged的命令
        private string _test3_Time;
        /// <summary>
        /// 当前事件
        /// </summary>
        public string Test3_CurrentTime
        {
            get { return _test3_Time; }
            set { SetProperty(ref _test3_Time, value); }
        }

        private bool _test3_CanUpdate;
        /// <summary>
        /// 是否允许更新1
        /// </summary>
        public bool Test3_CanUpdate
        {
            get { return _test3_CanUpdate; }
            set
            {
                SetProperty(ref _test3_CanUpdate, value);
            }
        }

        public DelegateCommand Test3_UpdateTime { get; set; }

        void Test3_UpdateTimeText()
        {
            Test3_CurrentTime = DateTime.Now.ToString();
        }

        bool Test3_CanUpdateTimeText()
        {
            return Test3_CanUpdate;
        }
        #endregion

        #region Test4_快速关联CanExcute
        private string _test4_Time;
        /// <summary>
        /// 当前事件
        /// </summary>
        public string Test4_CurrentTime
        {
            get { return _test4_Time; }
            set { SetProperty(ref _test4_Time, value); }
        }

        private bool _test4_CanUpdate;
        /// <summary>
        /// 是否允许更新1
        /// </summary>
        public bool Test4_CanUpdate
        {
            get { return _test4_CanUpdate; }
            set
            {
                SetProperty(ref _test4_CanUpdate, value);
            }
        }

        public DelegateCommand Test4_UpdateTime { get; set; }

        void Test4_UpdateTimeText()
        {
            Test4_CurrentTime = DateTime.Now.ToString();
        }
        #endregion

        #region Test5_关联多个属性
        private string _test5_Time;
        /// <summary>
        /// 当前事件
        /// </summary>
        public string Test5_CurrentTime
        {
            get { return _test5_Time; }
            set { SetProperty(ref _test5_Time, value); }
        }

        private bool _test5_CanUpdate1;
        /// <summary>
        /// 是否允许更新1
        /// </summary>
        public bool Test5_CanUpdate1
        {
            get { return _test5_CanUpdate1; }
            set
            {
                SetProperty(ref _test5_CanUpdate1, value);
            }
        }

        private bool _test5_CanUpdate2;
        /// <summary>
        /// 是否允许更新1
        /// </summary>
        public bool Test5_CanUpdate2
        {
            get { return _test5_CanUpdate2; }
            set
            {
                SetProperty(ref _test5_CanUpdate2, value);
            }
        }

        public DelegateCommand Test5_UpdateTime { get; set; }

        void Test5_UpdateTimeText()
        {
            Test5_CurrentTime = DateTime.Now.ToString();
        }
        #endregion

        #region Test6_异步命令
        private string _test6_Time;
        public string Test6_CurrentTime
        {
            get { return _test6_Time; }
            set { SetProperty(ref _test6_Time, value); }
        }

        public AsyncDelegateCommand Test6_UpdateTime { get; set; }

        async Task Test6_UpdateTimeText()
        {
            await Task.Delay(2000);
            Test6_CurrentTime = DateTime.Now.ToString();
        }
        #endregion

        #region Test7_复合命令
        public CompositeCommand Test7_UpdateTime { get; set; }
        #endregion

        public MainWindowViewModel()
        {
            Test1_UpdateTime = new DelegateCommand(Test1_UpdateTimeText);

            Test2_UpdateTime = new DelegateCommand<string>(Test2_UpdateTimeText);

            Test3_UpdateTime = new DelegateCommand(Test3_UpdateTimeText, Test3_CanUpdateTimeText).ObservesProperty(() => Test3_CanUpdate);

            // 仅和一个 bool 类型属性有关的命令，可以快速关联
            Test4_UpdateTime = new DelegateCommand(Test4_UpdateTimeText).ObservesCanExecute(() => Test4_CanUpdate);

            // 命令关联多个属性时
            Test5_UpdateTime = new DelegateCommand(Test5_UpdateTimeText, () => Test5_CanUpdate1 && Test5_CanUpdate2)
               .ObservesProperty(() => Test5_CanUpdate1)
               .ObservesProperty(() => Test5_CanUpdate2);

            Test6_UpdateTime = new AsyncDelegateCommand(Test6_UpdateTimeText);
            //Test6_UpdateTime = new AsyncDelegateCommand(Test6_UpdateTimeText).EnableParallelExecution(); // 允许重复执行命令

            Test7_UpdateTime = new CompositeCommand();
            Test7_UpdateTime.RegisterCommand(Test1_UpdateTime);
            Test7_UpdateTime.RegisterCommand(Test2_UpdateTime);
            Test7_UpdateTime.RegisterCommand(Test3_UpdateTime);
            Test7_UpdateTime.RegisterCommand(Test4_UpdateTime);
            Test7_UpdateTime.RegisterCommand(Test5_UpdateTime);
            Test7_UpdateTime.RegisterCommand(Test6_UpdateTime);
        }
    }
}